<!DOCTYPE html>
<html>
<head>
    <title>Physics Diagram</title>
    <style>
        body {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            flex-direction: column;
        }
        canvas {
            border: 1px solid #ccc;
        }
    </style>
</head>
<body>
    <canvas id="physics-canvas" width="500" height="450"></canvas>
    <p>习题 3-23 图</p>
    <script>
        const canvas = document.getElementById('physics-canvas');
        const ctx = canvas.getContext('2d');

        // Helper function to draw an arrowhead
        function drawArrowHead(ctx, x, y, angle, headLength = 10) {
            ctx.save();
            ctx.translate(x, y);
            ctx.rotate(angle);
            ctx.beginPath();
            ctx.moveTo(0, 0);
            ctx.lineTo(-headLength, headLength / 2);
            ctx.moveTo(0, 0);
            ctx.lineTo(-headLength, -headLength / 2);
            ctx.stroke();
            ctx.restore();
        }
        
        // Helper function to draw an arrow from (fromx, fromy) to (tox, toy)
        function drawArrow(ctx, fromx, fromy, tox, toy, headLength = 10) {
            const angle = Math.atan2(toy - fromy, tox - fromx);
            ctx.beginPath();
            ctx.moveTo(fromx, fromy);
            ctx.lineTo(tox, toy);
            ctx.stroke();
            
            ctx.save();
            ctx.translate(tox, toy);
            ctx.rotate(angle);
            ctx.beginPath();
            ctx.moveTo(0, 0);
            ctx.lineTo(-headLength, headLength / 2);
            ctx.moveTo(0, 0);
            ctx.lineTo(-headLength, -headLength / 2);
            ctx.stroke();
            ctx.restore();
        }

        // --- Main Drawing ---
        
        // Parameters and coordinates
        const cx = 250; // center x of the cylinder
        const cy = 280; // center y of the cylinder
        const radius = 90; // radius of the cylinder
        const h = 120; // height of the fall
        const theta = Math.PI / 4; // 45 degrees
        const ballRadius = 6;

        // Calculate coordinates of points B and A
        const x_B = cx - radius * Math.cos(theta);
        const y_B = cy - radius * Math.sin(theta);
        const x_A = x_B;
        const y_A = y_B - h;

        // Set drawing styles
        ctx.strokeStyle = 'black';
        ctx.fillStyle = 'black';
        ctx.lineWidth = 2;
        ctx.font = 'italic 22px Times New Roman';

        // 1. Draw the cylinder
        ctx.beginPath();
        ctx.arc(cx, cy, radius, 0, 2 * Math.PI);
        ctx.stroke();

        // 2. Draw the center O and its label
        ctx.fillText("O", cx - 25, cy + 8);

        // 3. Draw the radius OB
        ctx.beginPath();
        ctx.moveTo(cx, cy);
        ctx.lineTo(x_B, y_B);
        ctx.stroke();
        
        // 4. Draw the horizontal line from O
        ctx.beginPath();
        ctx.moveTo(cx, cy);
        ctx.lineTo(cx + radius, cy);
        ctx.stroke();

        // 5. Draw the angle arc and label for theta
        // The diagram shows the angle theta between OB and the horizontal axis.
        // The arc is drawn in the acute angle region between OB and the *left* horizontal axis.
        ctx.beginPath();
        ctx.arc(cx, cy, 35, Math.PI - theta, Math.PI);
        ctx.stroke();
        const angleLabelRadius = 50;
        const angleLabelAngle = Math.PI - theta / 2;
        ctx.fillText("θ", cx + angleLabelRadius * Math.cos(angleLabelAngle) - 5, cy - angleLabelRadius * Math.sin(angleLabelAngle) + 10);

        // 6. Draw point B and its label
        ctx.fillText("B", x_B - 25, y_B);

        // 7. Draw the falling ball at A (outline only)
        ctx.beginPath();
        ctx.arc(x_A, y_A, ballRadius, 0, 2 * Math.PI);
        ctx.stroke();

        // 8. Add labels for point A and mass m₀
        ctx.fillText("A", x_A - 25, y_A + 5);
        ctx.fillText("m", x_A - 5, y_A - 15);
        ctx.font = 'italic 16px Times New Roman';
        ctx.fillText("0", x_A + 9, y_A - 11);
        ctx.font = 'italic 22px Times New Roman';
        
        // 9. Draw the path of the ball
        // Solid arrow indicating initial motion
        const arrowLength = 35;
        drawArrow(ctx, x_A, y_A, x_A, y_A + arrowLength);
        
        // Dashed line for the rest of the path
        ctx.save();
        ctx.beginPath();
        ctx.setLineDash([5, 5]);
        ctx.moveTo(x_A, y_A + arrowLength);
        ctx.lineTo(x_B, y_B);
        ctx.stroke();
        ctx.restore();
        
        // 10. Draw the height indicator 'h'
        ctx.lineWidth = 1.5;
        const h_line_x = x_A + 80;
        
        // Top horizontal line at level A
        ctx.beginPath();
        ctx.moveTo(x_A, y_A);
        ctx.lineTo(h_line_x, y_A);
        ctx.stroke();
        
        // Bottom horizontal line at level B
        ctx.beginPath();
        ctx.moveTo(x_B, y_B);
        ctx.lineTo(h_line_x, y_B);
        ctx.stroke();

        // Vertical line with an arrowhead pointing down
        drawArrow(ctx, h_line_x, y_A, h_line_x, y_B);

        // Label 'h'
        ctx.fillText("h", h_line_x + 10, (y_A + y_B) / 2 + 8);

    </script>
</body>
</html>